/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.sapra.Prefactura;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
import nextapp.echo2.app.table.DefaultTableModel;
import nextapp.echo2.app.table.TableModel;
import org.sapra.core.DBManager;
import org.sapra.dep.BanorteCuenta;
import org.sapra.dao.Empresa;
import org.sapra.dao.Factura;
import org.sapra.dao.Periodo;
import org.sapra.dep.Poliza;
import org.sapra.dep.Practicante;
import org.sapra.dep.Usuario;
import org.sapra.dep.conexion.DAC_Ext;
import org.sapra.dep.conexion.DBWRAP;
import org.sapra.logon.dLogin;



/**
 *
 * @author ppratsc
 */
public class PrefacturaMO {

    private List<Practicante> m_practicantes;
    private int m_empresa=0;
    private double m_Comision = 0;
    private Periodo m_periodo;
    private Factura m_factura;
    private double m_SubTotal=0;

    private DBWRAP pdb;

    public double getSubTotal(){
        return m_SubTotal;
    }

        



    public PrefacturaMO() {
    }
    public Practicante getPracticante(int index){
        return m_practicantes.get(index);
    }

    public List<Practicante> getPracticantes(){
        return m_practicantes;
    }

    public double getComision(){
        return m_Comision;
    }

    public boolean Autorizar(Usuario usuario, Periodo periodo) {

        String sql;
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        int pkey=0;

        //SI LA FACTURA ESTA CERRADA, NO HAY NADA QUE HACER
        if(m_factura.isCerrada()) return false;
        DBWRAP db=new DBWRAP();
        // APERTURA DE LA FACTURA
        try {
            db.getConnection().setAutoCommit(false);
            
            //Graba factura en Tabla
            sql = "INSERT INTO factura(fec_autorizacion,razon_social,rfc,comision,iva,fk_periodo,autorizo)VALUES(";
            sql += "NOW(),"; //HOY
            sql += "'"+ getEmpresaName(m_empresa) +"',"; //RAZON SOCIAL
            sql += "'"+ getEmpresaRFC(m_empresa) +"',";  //RFC
            sql += getComisionEmpresa(m_empresa) + ",";  //COMISION
            sql += "0.16,"; // IVA
            sql += m_periodo.index + ",";
            sql += "'"+usuario.login +"'"+ ")";
            db.insert(sql);

            pdb=new DBWRAP();
            pdb.getConnection().setAutoCommit(false);
            //Graba los conceptos
            for(Iterator it = m_practicantes.iterator();it.hasNext();) {
                Practicante p = (Practicante) it.next();
                sql ="INSERT  INTO facturapartida(num_empleado,cuenta,nombre,paterno,materno,fec_inicio,fec_termino,fec_baja,beca,diaspagar,tmpMesesSeguro,seguroPracticante,seguroEmpresa,fk_periodoid,fk_convenioid,centrocosto,departamento) VALUES(";
                sql += (p.empleado != null)?"'" +p.empleado+ "',":"NULL,";
                sql += (p.cuenta != null)  ?"'" +p.cuenta  + "',":"NULL,";
                sql += "'" + p.nombre + "',";
                sql += "'" + p.paterno + "',";
                sql += "'" + p.materno + "',";
                sql += "'" + df.format(p.fechaInicio) + "',";
                sql += "'" + df.format(p.fechaTermino) + "',";
                sql += (p.fechaCancelacion != null)?"'" + df.format(p.fechaCancelacion)+"'":"NULL";
                sql += ",";
                sql += p.sueldo + ",";
                sql += p.dias + ",";
                sql += (p.poliza != null)?p.poliza.meses:"NULL";
                sql += ",";
                sql += p.polizaPracticante + ",";
                sql += p.polizaEmpresa + ",";
                sql += periodo.index+ ",";
                sql += p.id +",";
                sql += "'" + p.centro + "',";
                sql += "'" + p.departamento + "')";

                db.insert(sql);

            }

            db.getConnection().commit();
            db.close();
            db=null;
            m_factura.setCerrada(true) ;
            m_factura.setAutorizo(usuario.login);
            for(int i=0;i<ids.size();i++){
                int id=ids.get(i);
                DAC_Ext.UpdPolizaSeguro(periodo, true, id);
            
            }
        } catch (SQLException ex) {
            try {
                Logger.getLogger(PrefacturaMO.class.getName()).log(Level.SEVERE, null, ex);
                db.getConnection().rollback();
                if(db!=null){
                    db.close();
                    db=null;
                }

                return false;
            } catch (SQLException ex1) {
                Logger.getLogger(PrefacturaMO.class.getName()).log(Level.SEVERE, null, ex1);
                if(db!=null){
                    db.close();
                    db=null;
                }
            }
        }finally{
            try {
               
                if(db!=null){
                     db.getConnection().setAutoCommit(true);
                    db.close();
                    db=null;
                }
            } catch (SQLException ex) {
                Logger.getLogger(PrefacturaMO.class.getName()).log(Level.SEVERE, null, ex);
                if(db!=null){
                    db.close();
                    db=null;
                }
            }
        }

        return true;
    }

    public String Autorizo() {
        return m_factura.getAutorizo();
    }

    public boolean Cancelar(Periodo periodo) {
        boolean resp=true;
        DBWRAP db=new DBWRAP();
        String sql = "delete from factura where fk_periodo = " + periodo.index;

        try {
            db.update(sql);
            sql = "delete from facturapartida where fk_periodoid = " + periodo.index;
            db.update(sql);
            db.close();
            db=null;
        } catch (SQLException ex) {
            Logger.getLogger(PrefacturaMO.class.getName()).log(Level.SEVERE, null, ex);
            resp = false;
            if(db!=null){
                db.close();
                db=null;
            }
        }finally{
            if(db!=null){
                db.close();
                db=null;
            }
        }

        return resp;
    }

    public List<Periodo> getPeriodos( int empresa,int opc,org.sapra.dao.Practicante p)
    {
        SimpleDateFormat spd=new SimpleDateFormat("yyyy-MM-dd");
        String sql = " ";
        if(opc==0)
                sql+= "select calendarioFacturacionPracticantesId,dia_inicio,dia_fin,dias_a_pagar_periodo,dia_limite_aut_fac from calendariofacturacionpracticantes where fk_empresaid="+empresa+" ORDER BY dia_limite_aut_fac asc";
        if(opc==1)
            sql+=" SELECT  calendarioFacturacionPracticantesId,dia_inicio,dia_fin,dias_a_pagar_periodo,dia_limite_aut_fac FROM calendariofacturacionpracticantes "
                    + " WHERE NOT EXISTS (SELECT * FROM factura "
                    + " WHERE calendariofacturacionpracticantes.calendarioFacturacionPracticantesId = factura.fk_periodo) "
                    + " and (fk_empresaId="+empresa+" and (dia_fin>='"+spd.format(p.getFec_inicioContrato())+"' AND dia_fin<='"+spd.format(p.getFec_terminoContrato())+"')) order by dia_inicio ASC;";
        Date fi,ff,dl;
        String str;
        int id,dp;
        //DefaultListModel lm = new DefaultListModel();
        List<Periodo> resp = new  ArrayList<Periodo>();
        DBWRAP db=new DBWRAP();
        ResultSet data=null;
        try {
            data = db.select(sql);

            while(data.next())
            {
                id = data.getInt("calendarioFacturacionPracticantesId");
                fi = data.getDate("dia_inicio");
                ff = data.getDate("dia_fin");
                dp = data.getInt("dias_a_pagar_periodo");
                dl = data.getDate("dia_limite_aut_fac");
                resp.add(new Periodo(id,fi,ff,dp,dl));
            }
            data.close();
            data=null;
            db.close();
            db=null;
        }catch (Exception e){
            String ex = e.toString();
            try {
                if(data!=null){
                data.close();
                data=null;
            }
                if(db!=null){
                    db.close();
                     db=null;
                }
            } catch (Exception exc) {
            }finally{
                if(db!=null){
                    db.close();
                     db=null;
                }
            }
        }

        return resp;
    }

    public String getEmpresaName(int index)
    {
        String sql = "select empresaid,razon_factura from empresa where empresaid="+index;
        String resp=null;
        DBWRAP db=new DBWRAP();
        ResultSet data=null;
        try {
            data = db.select(sql);
            while(data.next())
            {
               resp =  data.getString("razon_factura");
            }
            data.close();
            data=null;
            db.close();
            db=null;
         }catch (Exception e){
            String ex = e.toString();
            try {
                if(data!=null){
                data.close();
                data=null;
            }
                if(db!=null){
                    db.close();
                     db=null;
                }
            } catch (Exception exc) {
            }finally{
                if(db!=null){
                    db.close();
                     db=null;
                }
            }
         }
        return resp;
    }

    public TableModel InitFactura(Empresa empresa,Periodo periodo) {

        m_practicantes = new ArrayList<Practicante>();
        DefaultTableModel tablemodel;
        m_empresa = empresa.getEmpresaId();
        m_periodo = periodo;
        boolean existe = false;
        // REVISA LA EXISTENCIA DE LA PREFACTURA
        m_factura = QueryFactura(periodo);

        if(!(m_factura.isCerrada())){
            // GENERA LA PREFACTURA
            // Se buscan los Practicantes a los que se le tiene que pagar
            QueryVigentes(m_empresa,periodo,m_practicantes); //Generico
            QueryVigProxCancelar(m_empresa,periodo,m_practicantes); // Generico que cancela despues
            QueryInician(m_empresa,periodo,m_practicantes); //Inician en Periodo
            QueryTerminan(m_empresa,periodo,m_practicantes); //Terminan en el Periodo
            QueryCancelan(m_empresa,periodo,m_practicantes); //Cancelan en el Periodo

            // Buscar los Numero de Cuenta (Ultimo Numero de Cuenta)
            QueryCuentas(m_empresa,periodo,m_practicantes);

            // SEÑALA PRACTICANTES CON SEGUROS RETROACTIVOS
            // Retroactivos(empresa,periodo,m_practicantes);

            // Buscar su la Poliza relacionada al Convenio y Calcula el Monto a Pagar si Aplica
            QuerySeguros(empresa,periodo,m_practicantes);

            // CONSULTA LOS DEPARTAMENTOS
            QueryDepartamentos(m_practicantes);

            // CONSULTA LOS CENTROS DE COSTO
            QueryCentrosCostos(m_practicantes);

            // Integra los Duplicados
            if(m_practicantes.size()!=0)
                blend(m_practicantes,periodo);

            

            // CONSULTA LOS AJUSTES/DEDUCCIONES
            QueryAjustes(m_practicantes,periodo);

            // Calcula los Netos
            if(m_practicantes.size()!=0)
                CalculaNetos(m_practicantes,periodo);

            // Busca/Corrige a los Practicantes que NO pueden pagar su seguro
            if( QueryPracticantesInsoventes(m_empresa,periodo,m_practicantes) ){
                CalculaNetos(m_practicantes,periodo);
            }


        }else {
            //CONSULTA LA PREFACTURA DE LA BASE DATOS
            QueryPartidas(periodo,m_practicantes);
            QueryAjustes(m_practicantes,periodo);

            // Calcula los Netos
            if(m_practicantes.size()!=0)
                CalculaNetos(m_practicantes,periodo);
        }


        //Genera el Modelo de Datos para el GUI
        tablemodel = new DefaultTableModel(18,0);
        
        int i=0;
        //Columnas de la Prefactura
        tablemodel.setColumnName(i++,"#");
        tablemodel.setColumnName(i++,"CUENTA");
        tablemodel.setColumnName(i++,"NETO");
        tablemodel.setColumnName(i++,"NOMBRE");
        tablemodel.setColumnName(i++,"PATERNO");
        tablemodel.setColumnName(i++,"MATERNO");
        tablemodel.setColumnName(i++,"CCOSTO");
        tablemodel.setColumnName(i++,"F.INICIO");
        tablemodel.setColumnName(i++,"F.TERMINO");
        tablemodel.setColumnName(i++,"F.BAJA");
        tablemodel.setColumnName(i++,"VIGENCIA");
        tablemodel.setColumnName(i++,"APORTACION MENSUAL");
        tablemodel.setColumnName(i++,"DIAS x PAGAR");
        tablemodel.setColumnName(i++,"AJUSTES");
        tablemodel.setColumnName(i++,"MONTO A PAGAR");
        tablemodel.setColumnName(i++,"SEGURO EMPRESA");
        tablemodel.setColumnName(i++,"SEGURO PRACTICANTE");
        tablemodel.setColumnName(i++,"DEDUCCIONES");

        //Rellena la Tabla
        Object[] item = {null,null,null, null,null,null,null, null, null, null, null, null, null, null, null, null, null, null, null, null, null};
        DecimalFormat nf = new DecimalFormat("##,###,###.00");
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MMM-dd",new Locale("es"));

        int partida=1;
        for(Iterator it = m_practicantes.iterator();it.hasNext();)
        {
            Practicante p = (Practicante) it.next();
            i=0;

            item[i++] = partida++;
            item[i++] = (p.cuenta != "")?p.cuenta:"N/D";
            item[i++] = nf.format(p.neto);
            item[i++] = p.nombre+p.id;
            item[i++] = p.paterno;
            item[i++] = p.materno;
            item[i++] = (p.centro != null)?p.centro:"N/D";
            item[i++] = df.format(p.fechaInicio);
            item[i++] = df.format(p.fechaTermino);
            item[i++] = (p.fechaCancelacion != null)?df.format(p.fechaCancelacion):"N/D";
            item[i++] = (p.poliza != null)?p.poliza.meses:"N/D";
            item[i++] = nf.format(p.sueldo);
            item[i++] = p.dias;
            item[i++] = nf.format(p.ajuste);
            item[i++] = nf.format(p.apagar);
            item[i++] = nf.format(p.polizaEmpresa);
            item[i++] = nf.format(p.polizaPracticante);
            item[i++] = nf.format(p.deduccion);

            tablemodel.addRow(item);
            System.out.println(item.toString());
        }

        return tablemodel;

    }

    public Periodo getPeriodo(int periodo) {
        String sql = "SELECT dias_a_pagar_periodo,dia_inicio,dia_fin,fk_empresaid,dia_limite_aut_fac from calendariofacturacionpracticantes";
        sql += " WHERE calendarioFacturacionPracticantesId = "+periodo;
        Periodo resp = null;
        ResultSet rs = null;
        int diaspagar = 0;
        int empresa = 0;
        Date ini,fin,dia_limite;
        DBWRAP db=new DBWRAP();
        db.getConnection();
        try {
            rs = db.select(sql);
            if(rs.next()){
                diaspagar = rs.getInt("dias_a_pagar_periodo");
                ini = rs.getDate("dia_inicio");
                fin = rs.getDate("dia_fin");
                empresa = rs.getInt("fk_empresaid");
                dia_limite=rs.getDate("dia_limite_aut_fac");
                resp = new Periodo(periodo,ini,fin,diaspagar,dia_limite);
                resp.empresa = empresa;
            }if(db!=null){
                    db.close();
                    db=null;
            }

        } catch (SQLException ex) {
            if(db!=null){
                    db.close();
                    db=null;
            }
            Logger.getLogger(PrefacturaMO.class.getName()).log(Level.SEVERE, null, ex);
        }finally{
            if(db!=null){
                    db.close();
                    db=null;
            }
        }

        return resp;
    }

    public boolean isCerrada() {
         return m_factura.isCerrada();
    }
    private double _TotalApagar=0;
    private double _AdmGasto=0;
    private double _SubTotalSS=0;
    private double _TotalSeguroEmpresa =0;
    private double _iva=0;
    private double _Total1=0;
    private double AdeudoTotal=0.00;
    private double AbonoTotal=0.00;

    public TableModel getTotales() {

        //Genera el Modelo de Datos para el GUI
        DefaultTableModel tablemodel = new DefaultTableModel(2,0);
        Object[] item = {null, null};
        double TotalApagar=0;
        double TotalSeguroEmpresa =0;
        double AdmGasto=0;
        AdeudoTotal=0.00;
        AbonoTotal=0.00;
        try {


        DecimalFormat nf = new DecimalFormat("##,###,###.00");
        DecimalFormat nf2 = new DecimalFormat("#####.00");
        m_Comision = getComisionEmpresa(m_empresa);
        tablemodel.setColumnName(0,"CONCEPTO");
        tablemodel.setColumnName(1,"MONTO");

        for(Iterator it = m_practicantes.iterator();it.hasNext();) {
            Practicante p = (Practicante) it.next();
            TotalApagar += p.apagar;
            TotalSeguroEmpresa += p.polizaEmpresa;
        }

        //Total de Becas
        item[0] = "Monto a Pagar";
        item[1] = nf.format(TotalApagar);
        _TotalApagar=TotalApagar;
        tablemodel.addRow(item);

        //Gasto Administrativo
        item[0] = (m_Comision*100) + "%  G.A.";
        AdmGasto = TotalApagar * m_Comision;
        _AdmGasto=AdmGasto;
        item[1] = nf.format(AdmGasto); //Consultar Gasto Administrativo
        tablemodel.addRow(item);

        //SubTotal sin Seguros
        item[0] = "SubTotal Sin Seguro";
        _SubTotalSS=TotalApagar + AdmGasto;
        item[1] = nf.format(TotalApagar + AdmGasto);
        tablemodel.addRow(item);

        //Seguro Empresa
        item[0] = "Seguro Empresa";
        _TotalSeguroEmpresa=TotalSeguroEmpresa;
        item[1] = nf.format(TotalSeguroEmpresa);
        tablemodel.addRow(item);

        //Adeudos Empresa
         DAC_Ext ext=new DAC_Ext();
        ArrayList<Object> lista=new ArrayList<Object>();
        Empresa em=dLogin.getEmpresa2(m_empresa);
        lista=ext.selectAbono(1, em.getEmpresaId(),m_periodo.index);
        for(int i=0;i<lista.size();i++){
                         Object[] o=new Object[4];
                         o=(Object[])lista.get(i);
                         double pago=Double.parseDouble(o[2]+"");
                         pago=Double.parseDouble(nf2.format(pago));
                         AdeudoTotal+=pago;
              }
        item[0] = "Adeudos Empresa";
        item[1] =  nf.format(AdeudoTotal);;
        tablemodel.addRow(item);

        //SubTotal con Seguro
        m_SubTotal = TotalApagar + AdmGasto + TotalSeguroEmpresa+AdeudoTotal;
        item[0] = "SubTotal con Seguro";
        item[1] = nf.format(m_SubTotal);
        tablemodel.addRow(item);

        //IVA
        item[0] = "I.V.A";
        _iva=m_SubTotal * .16;
        item[1] = nf.format(m_SubTotal * .16);
        tablemodel.addRow(item);

        //Total1
        item[0] = "Total1";
        _Total1=m_SubTotal + (m_SubTotal*.16);
        item[1] = nf.format(m_SubTotal + (m_SubTotal*.16));
        tablemodel.addRow(item);

        //Adeudos Empresa
       lista=ext.selectAbono(2, em.getEmpresaId(),m_periodo.index);
        for(int i=0;i<lista.size();i++){
                         Object[] o=new Object[4];
                         o=(Object[])lista.get(i);
                         double pago=Double.parseDouble(o[2]+"");
                         pago=Double.parseDouble(nf2.format(pago).toString());
                         AbonoTotal+=pago;
              }


        item[0] = "Abono Empresa";
        item[1] = nf.format(AbonoTotal);
        tablemodel.addRow(item);
        double SubTotalFinal=0.00;
        SubTotalFinal=_Total1-AbonoTotal;
        //Subtotal con Abonos
        item[0] = "SubTotal con Abonos";
        item[1] = nf.format(SubTotalFinal/1.16);
        tablemodel.addRow(item);

        //IVA
        item[0] = "I.V.A";
        item[1] = nf.format((SubTotalFinal/1.16)*.16);
        tablemodel.addRow(item);

        //Total Final
        item[0] = "Total Final";
        item[1] = nf.format(SubTotalFinal);
        tablemodel.addRow(item);
         } catch (Exception e) {
             e.printStackTrace();
        }
        return tablemodel;
    }

    public Usuario getUsuario(int index)
    {
        String sql = "select usuarioid,nombre,login,email,tipoUsuario from usuario where usuarioid="+index;
        Usuario usuario = new Usuario();
        DBWRAP db=new DBWRAP();
        db.getConnection();
        try {
            ResultSet data = db.select(sql);

            if(data.next())
            {
                usuario.email = data.getString("email");
                usuario.id = data.getInt("usuarioid");
                usuario.login = data.getString("login");
                usuario.tipo = data.getString("tipoUsuario");
                usuario.nombre = data.getString("nombre");
                usuario.email = data.getString("email");
                usuario.id = data.getInt("usuarioid");
                usuario.login = data.getString("login");
                usuario.tipo = data.getString("tipoUsuario");
                usuario.nombre = data.getString("nombre");

            }
            if(db!=null){
                    db.close();
                    db=null;
            }
         }catch (Exception e){
             if(db!=null){
                    db.close();
                    db=null;
            }
            String ex = e.toString();
        }finally{
            if(db!=null){
                    db.close();
                    db=null;
            }
        }
        return usuario;
    }

    private void CalculaNetos(List<Practicante> practicantes, Periodo periodo) {
        for(Iterator it = practicantes.iterator();it.hasNext();)
        {
            Practicante p = (Practicante) it.next();
            // Play-it-Safe: Si el numero de dias a pagar es mayor a numero
            // de dias a pagar en el periodo, iguala al maximo
            if(p.dias > periodo.diaspagar){
                p.dias = periodo.diaspagar;
            }
            DecimalFormat f = new DecimalFormat ("#######.##");
            p.neto = (p.sueldo) * p.dias;

            p.neto = p.neto / 30;      
            p.neto = p.neto +  p.ajuste; // Resta los Ajustes por la Empresa
            p.neto = p.neto +  p.deduccion; // Resta las deducciones por CAINTRA
            if((((int)p.neto -  (int)p.polizaPracticante))<0 && (int)p.polizaEmpresa==0){

                p.polizaPracticante=0;
                for(int i=0;i<ids.size();i++){
                        int idx=(Integer)ids.get(i);
                        if(p.id==idx)ids.remove(i);
                    }
            }else{
                p.neto = p.neto -  p.polizaPracticante;
            }
             //Resta Seguro por Practicante
            String form=f.format(p.neto);
            form=form.replace(',','.');
            p.neto=Double.parseDouble(form);
            //MXCN07-> Aqui tenemos que redondear el NETO hacia abajo
            p.neto=(int)p.neto;
            p.apagar = (p.sueldo / 30) * p.dias;
            p.apagar = p.apagar + p.ajuste;
        }
    }

    private void QueryAjustes(List<Practicante> practicantes,Periodo periodo) {

        
        ResultSet rs;
        double factor=0;
        double ajuste=0;
        boolean interno=false; // Es deduccion?
        boolean time=false;
         DBWRAP db=new DBWRAP();
        db.getConnection();
        for(Iterator it = practicantes.iterator();it.hasNext();)
        {
           
            String sql = "select factor,interno,tiempo from facturaajuste where fk_periodoid = " + periodo.index;
            ajuste = 0;
            try {
                Practicante p = (Practicante) it.next();
                sql += " and fk_convenioid = " + p.id;
                rs = db.select(sql);
                while(rs.next()){
                    factor = rs.getDouble("factor");
                    time = rs.getBoolean("tiempo");
                    interno = rs.getBoolean("interno");
                    if(time == true){
                        ajuste = (p.sueldo / 30) * factor;
                    }else {
                        ajuste = factor;
                    }
                    if(interno)
                        p.deduccion += ajuste;
                    else
                        p.ajuste += ajuste;
                }
               
            } catch (SQLException ex) {
                if(db!=null){
                    db.close();
                    db=null;
                 }
                Logger.getLogger(PrefacturaMO.class.getName()).log(Level.SEVERE, null, ex);
            }
             
        }if(db!=null){
                    db.close();
                    db=null;
                }
    }

    private void QueryCentrosCostos(List<Practicante> practicantes) {
       DBWRAP db=new DBWRAP();
        db.getConnection();
       for(Iterator it = practicantes.iterator();it.hasNext();)
        {
            Practicante p = (Practicante) it.next();
            String sql = "select b.nombre from practicante a,centrocosto b where a.fk_centrocostoId = b.centrocostoId and a.practicanteId =";
            sql += p.id;
            ResultSet rs;
            
            try {
                rs = db.select(sql);
                if(rs.next()){
                    p.centro = rs.getString("nombre");
                }
               
            } catch (SQLException ex) {
                    if(db!=null){
                        db.close();
                        db=null;
                    }
                Logger.getLogger(PrefacturaMO.class.getName()).log(Level.SEVERE, null, ex);
            }

             
        }if(db!=null){
                    db.close();
                    db=null;
                }
    }

    private void QueryCuentas(int empresa, Periodo periodo, List<Practicante> practicantes) {
        DAC_Ext ext=new DAC_Ext();practicantes.size();
        for(Iterator it = practicantes.iterator();it.hasNext();)
        {
            Practicante p = (Practicante) it.next();
            BanorteCuenta cuenta=ext.banorteCuenta(p.id);
            if(cuenta!=null){
                    if(cuenta.getNumCuenta().trim().equals("")||cuenta.getNumCuenta()==null)
                        p.cuenta="";
                    else
                         p.cuenta = cuenta.getNumCuenta();
                    if(cuenta.getNumTarjeta().trim().equals("")||cuenta.getNumTarjeta()==null)
                            p.numTarjeta="";
                    else
                            p.numTarjeta=cuenta.getNumTarjeta();

                    continue;
            }

        }
    }

    private void QueryDepartamentos(List<Practicante> practicantes) {
        DBWRAP db=new DBWRAP();
        db.getConnection();
        for(Iterator it = practicantes.iterator();it.hasNext();)
        {
            Practicante p = (Practicante) it.next();
            String sql = "select b.nombre from practicante a,departamento b where a.fk_departamentoId = b.departamentoId and a.practicanteId =";
            sql += p.id;
            ResultSet rs;
           
            try {
                rs = db.select(sql);
                if(rs.next()){
                    p.departamento = rs.getString("nombre");
                }
                
            } catch (SQLException ex) {
                if(db!=null){
                    db.close();
                    db=null;
                }
                Logger.getLogger(PrefacturaMO.class.getName()).log(Level.SEVERE, null, ex);
            }
        }if(db!=null){
                    db.close();
                    db=null;
                }
    }

    private Factura QueryFactura(Periodo periodo) {
        ResultSet rs;
        Factura resp = new Factura();
        List<Factura> lista;
        DBManager db2=new DBManager();
        try {
            lista=db2.getQuery(Factura.class,"SELECT * FROM factura WHERE fk_periodo = ?",periodo.index);
            if(lista.size()>0){
                resp=(Factura)lista.get(0);
                resp.setCerrada(true);
            }else{
                resp.setCerrada(false);
            }
        } catch (Exception ex) {
            Logger.getLogger(PrefacturaMO.class.getName()).log(Level.SEVERE, null, ex);
        }finally{
                
        }
        return resp;
    }

    private void QueryPartidas(Periodo periodo,List<Practicante> practicantes) {
        // Recupera las Partidas de la Prefactura Existente
        String sql;
        ResultSet rs;
        Practicante p;
        DBWRAP db=new DBWRAP();
        sql = "SELECT ";
        sql += "a.num_empleado,";
        sql += "a.cuenta,";
        sql += "a.nombre,";
        sql += "a.paterno,";
        sql += "a.materno,";
        sql += "a.beca,";
        sql += "a.fec_inicio,";
        sql += "a.fec_termino,";
        sql += "a.fec_baja,";
        sql += "a.diaspagar,";
        sql += "a.tmpMesesSeguro,";
        sql += "a.seguroPracticante,";
        sql += "a.seguroEmpresa,";
        sql += "a.departamento,";
        sql += "a.centrocosto,"; 
        sql += "a.fk_convenioid";
        sql += " FROM facturapartida a";
        sql += " WHERE ";
        sql += "a.fk_periodoid ="+periodo.index;
        try {
            rs = db.select(sql); // Consulta
            while(rs.next()){
                p = new Practicante();
                p.id = rs.getInt("fk_convenioid");
                p.empleado = rs.getString("num_empleado");
                p.cuenta = rs.getString("cuenta");
                p.nombre = rs.getString("nombre");
                p.paterno = rs.getString("paterno");
                p.materno = rs.getString("materno");
                p.fechaInicio = rs.getDate("fec_inicio");
                p.fechaTermino = rs.getDate("fec_termino");
                p.fechaCancelacion = rs.getDate("fec_baja");
                p.dias = rs.getInt("diaspagar");
                p.sueldo = rs.getDouble("beca");
                p.poliza = new Poliza();
                p.poliza.meses = rs.getInt("tmpMesesSeguro");
                p.polizaEmpresa = rs.getDouble("seguroEmpresa");
                p.polizaPracticante = rs.getDouble("seguroPracticante");
                p.departamento = rs.getString("departamento");
                p.centro = rs.getString("centrocosto");
                practicantes.add(p);
            }
            if(db!=null){
                    db.close();
                    db=null;
            }
        } catch (SQLException ex) {
            if(db!=null){
                    db.close();
                    db=null;
            }
            Logger.getLogger(PrefacturaMO.class.getName()).log(Level.SEVERE, null, ex);
        }finally{
            if(db!=null){
                    db.close();
                    db=null;
            }
        }
    }
    private ArrayList<Integer> ids=new ArrayList<Integer>();
    private void QuerySeguros(Empresa empresa,Periodo periodo,List<Practicante> practicantes) {
        int flag=0;
        int[] empId={38,379,88,321,322,324,90,89,87,323,85,94,84,86};
        Empresa emp=empresa;

        for(int h=0;h<empId.length;h++){
            if(emp.getEmpresaId()==empId[h])
                flag=1;
        }
        ids=new ArrayList<Integer>();

        for(int i=0;i<practicantes.size();i++){


            Practicante p = (Practicante)practicantes.get(i);
            if(flag!=1){
                    p.poliza = getPolizaPracticante(p,periodo);
                    if(p.poliza ==null)continue; // No tiene Poliza

                    if(p.poliza.pagaempresa)
                                            p.polizaEmpresa = p.poliza.costo / 1.16; // La empresa paga IVA total
                                    else{
                                        // El practicante PAGA el Seguro
                                        p.polizaPracticante = p.poliza.costo;
                                    }
                                    ids.add(p.id);
            }else{
                if(p.id==25106)
                    continue;

                p.poliza=new Poliza();
                if(p.id == 25106)
                    continue;
                if(emp.getEmpresaId() == 38 || emp.getEmpresaId() == 379){
                        p.polizaEmpresa = 129.31;
                }else{
                        p.polizaEmpresa = 60.34;
                }
            }
            
        }
    }

    private void RStoPracticante(ResultSet rs, List<Practicante> practicantes) {
        //Carga los Practicantes al Arreglo desde un ResultSet

        Practicante p;
        try {
            while (rs.next()) {
                p = new Practicante();
                p.id = rs.getInt("practicanteId");
                p.empleado = rs.getString("numEmpleado");
                p.nombre = rs.getString("nombre");
                p.paterno = rs.getString("paterno");
                p.materno = rs.getString("materno");
                p.fechaInicio = rs.getDate("fec_iniciocontrato");
                p.fechaTermino = rs.getDate("fec_terminocontrato");
                p.fechaCancelacion = rs.getDate("fec_cancelacion");
                p.sueldo = rs.getDouble("sueldo");
                practicantes.add(p);
            }
            rs.close();
            rs=null;
        } catch (SQLException ex) {
            try {
                if(rs!=null){
                    rs.close();
                    rs=null;
                }
            } catch (Exception e) {
            }
            Logger.getLogger(PrefacturaMO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return;
    }

    private void QueryVigentes(int empresa, Periodo periodo, List<Practicante> practicantes) {
        //Busca Practicantes que:
        //-->Se encuentren Vigentes
        //-->Que NO esten cancelados
        //-->Que no Terminen ni inicien en el periodo
        String sql;
        ResultSet rs;
        DBWRAP db=new DBWRAP();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        List<Practicante> ltemp = new ArrayList<Practicante>();

        sql = "SELECT ";
        sql += "a.practicanteId,";
        sql += "a.numEmpleado,";
        sql += "a.nombre,";
        sql += "a.paterno,";
        sql += "a.materno,";
        sql += "a.fec_iniciocontrato,";
        sql += "a.fec_terminocontrato,";
        sql += "a.fec_cancelacion,";
        sql += "a.sueldo";
        sql += " FROM ";
        sql += "practicante a,";
        sql += "empresa e,";
        sql += "departamento d";
        sql += " WHERE ";
        sql += "a.fk_departamentoId = d.departamentoId and ";
        sql += "e.empresaid = d.fk_empresaId and ";
        sql += "a.fec_cancelacion IS NULL and ";
        sql += "a.fec_iniciocontrato <= '"  + format.format(periodo.ini) + "' and ";
        sql += "a.fec_terminoContrato >= '" + format.format(periodo.fin) + "' and ";
        sql += "d.fk_empresaid ="+empresa;
         System.out.println("Query Vigentes");
        System.out.println(sql);
        try {
            rs = db.select(sql); // Consulta
            RStoPracticante(rs,ltemp);
            if(db!=null){
                    db.close();
                    db=null;
            }
        } catch (SQLException ex) {
            if(db!=null){
                    db.close();
                    db=null;
            }
            Logger.getLogger(PrefacturaMO.class.getName()).log(Level.SEVERE, null, ex);
        }

        //Agrega los Dias Trabajados por los Practicantes
        for(Iterator it = ltemp.iterator();it.hasNext();)
        {
            Practicante p = (Practicante) it.next();
            //p.dias=Laborales.universalDay(p,periodo);
            //p.dias = (int) periodo.diaspagar;
            //p.inicia = p.fechaInicio.equals(periodo.ini); //Checa si empieza en este periodo
            practicantes.add(p);
        }
        return;

    }

     private void QueryVigProxCancelar(int empresa, Periodo periodo, List<Practicante> practicantes) {
        //Busca Practicantes que:
        //-->Se encuentren Vigentes
        //-->Que se cancelen despues del periodo
        //-->Que no Terminen ni inicien en el periodo
        String sql;
        ResultSet rs;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        List<Practicante> ltemp = new ArrayList<Practicante>();
        DBWRAP db=new DBWRAP();
        sql = "SELECT ";
        sql += "a.practicanteId,";
        sql += "a.numEmpleado,";
        sql += "a.nombre,";
        sql += "a.paterno,";
        sql += "a.materno,";
        sql += "a.fec_iniciocontrato,";
        sql += "a.fec_terminocontrato,";
        sql += "a.fec_cancelacion,";
        sql += "a.sueldo";
        sql += " FROM ";
        sql += "practicante a,";
        sql += "empresa e,";
        sql += "departamento d";
        sql += " WHERE ";
        sql += "a.fk_departamentoId = d.departamentoId and ";
        sql += "e.empresaid = d.fk_empresaId and ";
        sql += "a.fec_cancelacion IS NOT NULL and ";
        sql += "a.fec_cancelacion > " +"'" + format.format(periodo.fin) +"'" +" and ";
        sql += "a.fec_iniciocontrato <= '"  + format.format(periodo.ini) + "' and ";
        sql += "a.fec_terminoContrato >= '" + format.format(periodo.fin) + "' and ";
        //Checar esta linea(no se admiten bajas posteriores a la fecha de terminacion
        //del convenio
        sql += "a.fec_terminoContrato >= a.fec_cancelacion and ";
        sql += "d.fk_empresaid ="+empresa;
         System.out.println("Query Vig prox a cancelar");
        System.out.println(sql);
        try {
            rs = db.select(sql); // Consulta
            RStoPracticante(rs,ltemp);
            if(db!=null){
                    db.close();
                    db=null;
            }
        } catch (SQLException ex) {
            if(db!=null){
                    db.close();
                    db=null;
            }
            Logger.getLogger(PrefacturaMO.class.getName()).log(Level.SEVERE, null, ex);
        }finally{
            if(db!=null){
                    db.close();
                    db=null;
            }
        }

        //Agrega los Dias Trabajados por los Practicantes
        for(Iterator it = ltemp.iterator();it.hasNext();)
        {
            Practicante p = (Practicante) it.next();
//            p.dias = Laborales.universalDay(p,periodo);//(int) periodo.diaspagar;
            practicantes.add(p);
        }
        return;


     }

    private void QueryInician(int empresa, Periodo periodo, List<Practicante> practicantes) {
        //Busca Practicantes que:
        //-->Se encuentren Vigentes
        //-->e inician en el periodo
        //-->Y No se encuentren cancelados
        String sql;
        ResultSet rs;
        DBWRAP db=new DBWRAP();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        List<Practicante> ltemp = new ArrayList<Practicante>();

        sql = "SELECT ";
        sql += "a.practicanteId,";
        sql += "a.numEmpleado,";
        sql += "a.nombre,";
        sql += "a.paterno,";
        sql += "a.materno,";
        sql += "a.fec_iniciocontrato,";
        sql += "a.fec_terminocontrato,";
        sql += "a.fec_cancelacion,";
        sql += "a.sueldo";
        sql += " FROM ";
        sql += "practicante a,";
        sql += "empresa e,";
        sql += "departamento d";
        sql += " WHERE ";
        sql += "a.fk_departamentoId = d.departamentoId and ";
        sql += "e.empresaid = d.fk_empresaId and ";
        //sql += "a.fec_cancelacion IS NULL and ";
        sql += "a.fec_iniciocontrato > '"  + format.format(periodo.ini) + "' and ";
        sql += "a.fec_iniciocontrato <= '" + format.format(periodo.fin) + "' and ";
        sql += "d.fk_empresaid ="+empresa;
        System.out.println("Query Inician");
        System.out.println(sql);
        try {
            rs = db.select(sql); // Consulta
            RStoPracticante(rs,ltemp);
            if(db!=null){
                    db.close();
                    db=null;
            }
        } catch (SQLException ex) {
            if(db!=null){
                    db.close();
                    db=null;
            }
            Logger.getLogger(PrefacturaMO.class.getName()).log(Level.SEVERE, null, ex);
        }finally{
            if(db!=null){
                    db.close();
                    db=null;
            }
        }

        //Agrega los Dias Trabajados por los Practicantes
        for(Iterator it = ltemp.iterator();it.hasNext();)
        {
            Practicante p = (Practicante) it.next();
//            p.dias = Laborales.universalDay(p,periodo);
            p.inicia = true;
            practicantes.add(p);
        }
        return;
    }

    private void QueryTerminan(int empresa, Periodo periodo, List<Practicante> practicantes) {
        //Busca Practicantes que:
        //-->Se encuentren Vigentes
        //-->Y Terminan en el Periodo
        //-->Y No se encuentren cancelados
        String sql;
        ResultSet rs;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat fmt = new SimpleDateFormat("dd");
        DBWRAP db=new DBWRAP();
        List<Practicante> ltemp = new ArrayList<Practicante>();

        sql = "SELECT ";
        sql += "a.practicanteId,";
        sql += "a.numEmpleado,";
        sql += "a.nombre,";
        sql += "a.paterno,";
        sql += "a.materno,";
        sql += "a.fec_iniciocontrato,";
        sql += "a.fec_terminocontrato,";
        sql += "a.fec_cancelacion,";
        sql += "a.sueldo";
        sql += " FROM ";
        sql += "practicante a,";
        sql += "empresa e,";
        sql += "departamento d";
        sql += " WHERE ";
        sql += "a.fk_departamentoId = d.departamentoId and ";
        sql += "e.empresaid = d.fk_empresaId and ";
        sql += "a.fec_cancelacion IS NULL and ";
        sql += "a.fec_terminoContrato >= '"  + format.format(periodo.ini) + "' and ";
        sql += "a.fec_terminoContrato <= '" + format.format(periodo.fin) + "' and ";
        sql += "d.fk_empresaid ="+empresa;
         System.out.println("Query Terminan");
        System.out.println(sql);
        try {
            rs = db.select(sql); // Consulta
            RStoPracticante(rs,ltemp);
            if(db!=null){
                    db.close();
                    db=null;
            }
        } catch (SQLException ex) {
            if(db!=null){
                    db.close();
                    db=null;
            }
            Logger.getLogger(PrefacturaMO.class.getName()).log(Level.SEVERE, null, ex);
        }finally{
            if(db!=null){
                    db.close();
                    db=null;
            }
        }

        //Agrega los Dias Trabajados por los Practicantes
        long offset;

        for(Iterator it = ltemp.iterator();it.hasNext();)
        {
            Practicante p = (Practicante) it.next();
//            p.dias = Laborales.universalDay(p,periodo);//Laborales.DayCountTerminan(periodo, p);
            practicantes.add(p);
        }

        return;
    }

    private void QueryCancelan(int empresa, Periodo periodo, List<Practicante> practicantes) {
        //Busca Practicantes que:
        //-->Se encuentren Vigentes
        //-->Que se cancelen en este periodo
        String sql;
        ResultSet rs;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat fmt = new SimpleDateFormat("dd");
        List<Practicante> ltemp = new ArrayList<Practicante>();
        DBWRAP db=new DBWRAP();

        sql = "SELECT ";
        sql += "a.practicanteId,";
        sql += "a.numEmpleado,";
        sql += "a.nombre,";
        sql += "a.paterno,";
        sql += "a.materno,";
        sql += "a.fec_iniciocontrato,";
        sql += "a.fec_terminocontrato,";
        sql += "a.fec_cancelacion,";
        sql += "a.sueldo";
        sql += " FROM ";
        sql += "practicante a,";
        sql += "empresa e,";
        sql += "departamento d";
        sql += " WHERE ";
        sql += "a.fk_departamentoId = d.departamentoId and ";
        sql += "e.empresaid = d.fk_empresaId and ";
        sql += "a.fec_cancelacion IS NOT NULL and ";
        sql += "a.fec_cancelacion >= '"  + format.format(periodo.ini) + "' and ";
        sql += "a.fec_cancelacion <= '" + format.format(periodo.fin) + "' and ";
        sql += "a.fec_cancelacion > a.fec_iniciocontrato and ";
        sql += "a.fec_cancelacion <= a.fec_terminocontrato and ";
        //sql += "a.fec_iniciocontrato <= '"  + format.format(periodo.ini) + "' and ";
        //sql += "a.fec_terminoContrato <= '" + format.format(periodo.fin) + "' and ";
        sql += "d.fk_empresaid ="+empresa;
         System.out.println("Query Cancelan");
        System.out.println(sql);

        try {
            rs = db.select(sql); // Consulta
            RStoPracticante(rs,ltemp);
            if(db!=null){
                    db.close();
                    db=null;
            }
        } catch (SQLException ex) {
            if(db!=null){
                    db.close();
                    db=null;
            }
            Logger.getLogger(PrefacturaMO.class.getName()).log(Level.SEVERE, null, ex);
        }finally{
            if(db!=null){
                    db.close();
                    db=null;
            }
        }
        //Agrega los Dias Trabajados por los Practicantes
        long offset;

        for(Iterator it = ltemp.iterator();it.hasNext();)
        {
            Practicante p = (Practicante) it.next();
//            p.dias = Laborales.universalDay(p,periodo);//Laborales.DayCountCancelan(periodo, p);
            practicantes.add(p);
        }

        return;
    }

    private void blend(List<Practicante> practicantes,Periodo per) {
        Collections.sort(practicantes); // Ordena por Nombre y Apellido

        // Aplicamos la e-logica del la UANL
        int i=0;

        //Toma el Primer Registro
        Practicante p1 = (Practicante) practicantes.get(i);
        SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
        //if(practicantes.size() < 2)return; // No hay nada que comprar

        //MXCN03-> Al parecer No se estan desduplicando los registros

        //Recorre la lista Buscando Duplicados
        if(practicantes.size() < 2){ // No hay nada que comprar
        HashMap hm;
        for(i=1;i < practicantes.size();i++)
        {

            int cont=0;
            Practicante p2 = (Practicante) practicantes.get(i);


            if(     p1.nombre.trim().equals(p2.nombre.trim()) &&
                    p1.paterno.trim().equals(p2.paterno.trim()) &&
                    p1.materno.trim().equals(p2.materno.trim())  ){
                    String str=p1.id+" "+p1.nombre+" "+p1.paterno+" "+p1.materno+" "
                            + " "+f.format(p1.fechaInicio)+" "+f.format(p1.fechaTermino)+" ";//+f.format(p1.fechaCancelacion);
                    // Es una Renovacion porque es el mismo Nombre
                    
                    if( p1.fechaInicio.equals(p2.fechaCancelacion)   ||
                        p1.fechaInicio.equals(p2.fechaTermino)      ||
                        p2.fechaInicio.equals(p1.fechaCancelacion)   ||
                        p2.fechaInicio.equals(p1.fechaTermino)){
                        // Es una Renovacion (Fechas Translapadas)
                        hm=Laborales.universalDay(p1, per);
                        int dia1=(Integer)hm.get("dias");
                        Date ini1=(Date)hm.get("inicio");
                        Date fin1=(Date)hm.get("fin");

                        hm=Laborales.universalDay(p2, per);
                        int dia2=(Integer)hm.get("dias");
                        Date ini2=(Date)hm.get("inicio");
                        Date fin2=(Date)hm.get("fin");
                        if((ini1.equals(per.ini) && fin1.equals(per.fin)) || (ini2.equals(per.ini) && fin2.equals(per.fin)))
                            p1.dias=per.diaspagar;
                        else{
                             if(ini1.equals(per.ini)){
                                if(fin2.equals(per.fin))
                                    p1.dias=per.diaspagar;
                                }else{
                                        if(ini2.equals(per.ini)){
                                            if(fin1.equals(per.fin))
                                                p1.dias=per.diaspagar;
                                        }else{
                                            p1.dias = (dia1 + dia2) -1; // Se suman los dias y Se resta un dia
                                        }

                                }
                        }

                        
                    }else
                    {
                        hm=Laborales.universalDay(p1, per);
                        int dia1=(Integer)hm.get("dias");
                        hm=Laborales.universalDay(p2, per);
                        int dia2=(Integer)hm.get("dias");
                        p1.dias =(dia1 + dia2); // Se suman los dias
                    }
                    // Se queda el convenio mas actual (orden de la base de datos)
                    Poliza poliza=new Poliza();
                    if(p1.poliza!=null){
                        poliza=p1.poliza;
                    }else if(p2 !=null)
                            poliza=p2.poliza;


                    p1.ajuste += p2.ajuste;
                    p1.deduccion += p2.deduccion;
                    p1.poliza=poliza;
                    practicantes.remove(p2);
                    i--;
            }else{
                
                if(p1.dias == 0){
                    hm=Laborales.universalDay(p1, per);
                    Date ini=(Date)hm.get("inicio");
                    Date fin=(Date)hm.get("fin");
                    Date fe=new Date();
                    
                    int dia1=(Integer)hm.get("dias");
                    if(ini.after(per.ini)){
                        Calendar c=Calendar.getInstance();
                        c.setTime(fin);
                        int mes=c.get(Calendar.MONTH);
                        if(mes==1)
                            dia1=dia1+2;
                    }
                    p1.dias=dia1;
                }

                //p2.dias=0;
                p1 = p2;
            }
                
        }
        if(i == practicantes.size()){
            if(p1.dias == 0){
                hm=Laborales.universalDay(p1, per);
                Date ini=(Date)hm.get("inicio");
                    Date fin=(Date)hm.get("fin");
                    int dia1=(Integer)hm.get("dias");
                    if(ini.after(per.ini)){
                        Calendar c=Calendar.getInstance();
                        c.setTime(fin);
                        int mes=c.get(Calendar.MONTH);
                        if(mes==1)
                            dia1=dia1+2;
                    }
                    p1.dias=dia1;
            }
        }
    }else{
                    HashMap hm;
        for(i=1;i < practicantes.size();i++)
        {

            int cont=0;
            Practicante p2 = (Practicante) practicantes.get(i);


            if(     p1.nombre.trim().equals(p2.nombre.trim()) &&
                    p1.paterno.trim().equals(p2.paterno.trim()) &&
                    p1.materno.trim().equals(p2.materno.trim())  ){
                    String str=p1.id+" "+p1.nombre+" "+p1.paterno+" "+p1.materno+" "
                            + " "+f.format(p1.fechaInicio)+" "+f.format(p1.fechaTermino)+" ";//+f.format(p1.fechaCancelacion);
                    // Es una Renovacion porque es el mismo Nombre

                    if( p1.fechaInicio.equals(p2.fechaCancelacion)   ||
                        p1.fechaInicio.equals(p2.fechaTermino)      ||
                        p2.fechaInicio.equals(p1.fechaCancelacion)   ||
                        p2.fechaInicio.equals(p1.fechaTermino)){
                        // Es una Renovacion (Fechas Translapadas)
                        hm=Laborales.universalDay(p1, per);
                        int dia1=(Integer)hm.get("dias");
                        Date ini1=(Date)hm.get("inicio");
                        Date fin1=(Date)hm.get("fin");

                        hm=Laborales.universalDay(p2, per);
                        int dia2=(Integer)hm.get("dias");
                        Date ini2=(Date)hm.get("inicio");
                        Date fin2=(Date)hm.get("fin");
                        if((ini1.equals(per.ini) && fin1.equals(per.fin)) || (ini2.equals(per.ini) && fin2.equals(per.fin)))
                            p1.dias=per.diaspagar;
                        else{
                             if(ini1.equals(per.ini)){
                                if(fin2.equals(per.fin))
                                    p1.dias=per.diaspagar;
                                }else{
                                        if(ini2.equals(per.ini)){
                                            if(fin1.equals(per.fin))
                                                p1.dias=per.diaspagar;
                                        }else{
                                            p1.dias = (dia1 + dia2) -1; // Se suman los dias y Se resta un dia
                                        }

                                }
                        }


                    }else
                    {
                        hm=Laborales.universalDay(p1, per);
                        //System.out.println("posible error"+p1.toString()+p1.fechaCancelacion.toString());
                        int dia1=(Integer)hm.get("dias");
                        hm=Laborales.universalDay(p2, per);
                        int dia2=(Integer)hm.get("dias");
                        p1.dias =(dia1 + dia2); // Se suman los dias
                    }
                    // Se queda el convenio mas actual (orden de la base de datos)
                    Poliza poliza=new Poliza();
                    if(p1.poliza!=null){
                        poliza=p1.poliza;
                    }else if(p2 !=null)
                            poliza=p2.poliza;


                    p1.ajuste += p2.ajuste;
                    p1.deduccion += p2.deduccion;
                    p1.poliza=poliza;
                    practicantes.remove(p2);
                    i--;
            }else{

                if(p1.dias == 0){
                    hm=Laborales.universalDay(p1, per);
                    Date ini=(Date)hm.get("inicio");
                    Date fin=(Date)hm.get("fin");
                    Date fe=new Date();

                    int dia1=(Integer)hm.get("dias");
                    if(ini.after(per.ini)){
                        Calendar c=Calendar.getInstance();
                        c.setTime(fin);
                        int mes=c.get(Calendar.MONTH);
                        if(mes==1)
                            dia1=dia1+2;
                    }
                    p1.dias=dia1;
                }

                //p2.dias=0;
                p1 = p2;
            }

        }
        if(i == practicantes.size()){
            if(p1.dias == 0){
                hm=Laborales.universalDay(p1, per);
                Date ini=(Date)hm.get("inicio");
                    Date fin=(Date)hm.get("fin");
                    int dia1=(Integer)hm.get("dias");
                    if(ini.after(per.ini)){
                        Calendar c=Calendar.getInstance();
                        c.setTime(fin);
                        int mes=c.get(Calendar.MONTH);
                        if(mes==1)
                            dia1=dia1+2;
                    }
                    p1.dias=dia1;
            }
        }

    }
 System.out.println(practicantes.toString());

    }
    public void comparacion(Practicante p1,Practicante p2,Periodo per){



    }
    public void obtenerDias(Practicante p,Periodo per){
        Date p_ini,p_fin,p_canc;
        p_ini=p.fechaInicio;
        p_fin=p.fechaTermino;
        p_canc=p.fechaCancelacion;
        Calendar cal=Calendar.getInstance();
        if(p_ini.getTime()>per.ini.getTime()){
            if(p.fechaCancelacion!=null){
                if(p.fechaCancelacion.getTime()<=per.fin.getTime()){

                }
            }else{
                if(p.fechaTermino.getTime()<=per.fin.getTime()){

                }
            }

        }else{



        }
    }
    public void countDays(Date f1,Date f2){

    }

    private double getComisionEmpresa(int id) {
        String sql = "select porcentaje_comision from empresa where empresaid = "+id;
        ResultSet rs;
        DBWRAP db=new DBWRAP();
        double resp = 0;
        try {
            rs = db.select(sql); // Consulta
            while(rs.next())
                resp = (double) rs.getInt("porcentaje_comision");
            if(resp != 0)resp = resp / 100;
            if(db!=null){
                    db.close();
                    db=null;
            }
        } catch (SQLException ex) {
            if(db!=null){
                    db.close();
                    db=null;
            }
            Logger.getLogger(PrefacturaMO.class.getName()).log(Level.SEVERE, null, ex);
        }finally{
            if(db!=null){
                    db.close();
                    db=null;
            }
        }
        return resp;
    }

    private String getCuentaPracticante(int id) {
        String sql = "SELECT numCuenta FROM banorte_cuentas WHERE fk_practicanteId = "+id;
        DBWRAP db=new DBWRAP();
        ResultSet rs;
        String resp = null;
        try {
            rs = db.select(sql); // Consulta
            while(rs.next())resp = rs.getString("numCuenta");
            if(db!=null){
                    db.close();
                    db=null;
            }
        } catch (SQLException ex) {
            if(db!=null){
                    db.close();
                    db=null;
            }
            Logger.getLogger(PrefacturaMO.class.getName()).log(Level.SEVERE, null, ex);
        }finally{
            if(db!=null){
                    db.close();
                    db=null;
            }
        }
        return resp;
    }

    private String getEmpresaRFC(int empresa) {
        String sql = "select rfc from empresa where empresaid = "+empresa;
        ResultSet rs;
        String resp = new String();
        DBWRAP db=new DBWRAP();
        try {
            rs = db.select(sql); // Consulta
            while(rs.next())resp = rs.getString("rfc");
            if(db!=null){
                    db.close();
                    db=null;
            }
        } catch (SQLException ex) {
            if(db!=null){
                    db.close();
                    db=null;
            }
            Logger.getLogger(PrefacturaMO.class.getName()).log(Level.SEVERE, null, ex);
        }finally{
            if(db!=null){
                    db.close();
                    db=null;
            }
        }
        return resp;
    }

    private Poliza getPolizaPracticante(Practicante p,Periodo per) {
        String sql;
        Poliza resp = null;
        ResultSet rs;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String fec_ini=format.format(per.ini);
        String fec_fin=format.format(per.fin);
        DBWRAP db=new DBWRAP();

        sql = "SELECT a.polizaseguroid, "
                + " a.fec_inicio, "
                + " a.fec_termino, "
                + " a.fec_cancelacion, "
                + " a.cobrarPolizaAEmpresa, "
                + " a.pagado, "
                + " b.costoPoliza, "
                + " b.nombre, "
                + " b.mesesAmparados, "
                + " b.fk_aseguradoraId, "
                + " b.planseguroId  "
                + " FROM polizaseguro a "
                + " INNER JOIN planseguro b "
                + " ON  a.fk_planSeguroId = b.planSeguroId"
                + " WHERE  (fk_prefacturaId="+per.index+"   AND pagado=false) AND fk_practicanteid =" + p.id +" ";


        try {
            System.out.println(sql);
            rs = db.select(sql); // Consulta
            while(rs.next()){
                resp = new Poliza();
                resp.costo = rs.getDouble("costoPoliza");
                resp.aseguradora = rs.getInt("fk_aseguradoraId");
                resp.ini = rs.getDate("fec_inicio");
                resp.fin = rs.getDate("fec_termino");
                resp.meses = rs.getInt("mesesAmparados");
                resp.pagaempresa = rs.getBoolean("cobrarPolizaAEmpresa");
                resp.pagado=rs.getInt("pagado");
                resp.planseguroId=rs.getInt("planseguroId");
            }
            if(db!=null){
                    db.close();
                    db=null;
            }
        } catch (SQLException ex) {
            if(db!=null){
                    db.close();
                    db=null;
            }
            Logger.getLogger(PrefacturaMO.class.getName()).log(Level.SEVERE, null, ex);
        }finally{
            if(db!=null){
                    db.close();
                    db=null;
            }
        }



        return resp;
    }

    public String isVencidos() {
        //Busca si hay practicantes que vencen en este periodo
        for(Iterator it = m_practicantes.iterator();it.hasNext();)
        {
            Practicante p = (Practicante) it.next();

            // Si existe fecha de cancelacion ignora al practicante
            if(p.fechaCancelacion != null) {
                //Validaciones a la Fecha de Cancelacion
                continue;
            }

            // Si el practicante NO esta cancelado y termina en este periodo
            long offset = m_periodo.fin.getTime() - p.fechaTermino.getTime();
            if(offset > 0) {  // Si vence en este periodo y no es el ultimo dia
                return p.nombre + " " + p.paterno + " " + p.materno;
            }
        }
        return null;
    }

    public String isNetoNegativo() {
        //Busca si hay practicantes que vencen en este periodo
        for(Iterator it = m_practicantes.iterator();it.hasNext();)
        {
            Practicante p = (Practicante) it.next();
            if(p.neto < 0){ // Si el NETO es negativo
                return p.nombre + " " + p.paterno + " " + p.materno;
            }
        }
        return null;
    }

    public boolean isFaltanCuentas(){
        // Busca si Faltan Cuentas en la Prefactura
        for(Iterator it = m_practicantes.iterator();it.hasNext();)
        {
            Practicante p = (Practicante) it.next();
            if(p.cuenta == null) {
                return true;
            }else if(p.cuenta.length() == 0) return true;
        }

        return false;
    }

    /*Copia de PrefacturaMO solo me regresa el ArrayList     */


    public List<Practicante> getM_practicantes() {
        return m_practicantes;
    }

    public void setM_practicantes(List<Practicante> m_practicantes) {
        this.m_practicantes = m_practicantes;
    }

    public double getAdmGasto() {
        return _AdmGasto;
    }

    public void setAdmGasto(double _AdmGasto) {
        this._AdmGasto = _AdmGasto;
    }

    public double getTotalApagar() {
        return _TotalApagar;
    }

    public void setTotalApagar(double _TotalApagar) {
        this._TotalApagar = _TotalApagar;
    }

    public double getTotalSeguroEmpresa() {
        return _TotalSeguroEmpresa;
    }

    public void setTotalSeguroEmpresa(double _TotalSeguroEmpresa) {
        this._TotalSeguroEmpresa = _TotalSeguroEmpresa;
    }

    public double getM_Comision() {
        return m_Comision;
    }

    public void setM_Comision(double m_Comision) {
        this.m_Comision = m_Comision;
    }

    public double getM_SubTotal() {
        return m_SubTotal;
    }

    public void setM_SubTotal(double m_SubTotal) {
        this.m_SubTotal = m_SubTotal;
    }

    public int getM_empresa() {
        return m_empresa;
    }

    public void setM_empresa(int m_empresa) {
        this.m_empresa = m_empresa;
    }

    public Factura getM_factura() {
        return m_factura;
    }

    public void setM_factura(Factura m_factura) {
        this.m_factura = m_factura;
    }

    public Periodo getM_periodo() {
        return m_periodo;
    }

    public void setM_periodo(Periodo m_periodo) {
        this.m_periodo = m_periodo;
    }

    public double getSubTotalSS() {
        return _SubTotalSS;
    }

    public void setSubTotalSS(double _SubTotalSS) {
        this._SubTotalSS = _SubTotalSS;
    }

    public double getTotal1() {
        return _Total1;
    }

    public void setTotal1(double _Total1) {
        this._Total1 = _Total1;
    }

    public double getIva() {
        return _iva;
    }

    public void setIva(double _iva) {
        this._iva = _iva;
    }

    private void Retroactivos(int empresa, Periodo actual, List<Practicante> practicantes) {


        Periodo anterior=null;
        List<Periodo> periodos = getPeriodos(empresa,0,null);
        long offset=0;
        final long DIA = 3600*24;

        if(periodos.size() <= 0) return; // Si no hay periodos sale...

        for(Iterator ix = periodos.iterator();ix.hasNext();){
            Periodo per = (Periodo) ix.next();
            offset = actual.ini.getTime() - per.fin.getTime();
            if(offset == DIA){
                anterior = per;
                break; // Encontramos el Periodo Anterior
            }
        }

        if(anterior == null) return; // Si no Existe Periodo Anterior sale
        boolean retro = false;
        for(Iterator it = practicantes.iterator();it.hasNext();)
        {
            retro = false;
            Practicante p = (Practicante) it.next();
            //Inicio en el Periodo Anterior?
            if(p.fechaInicio.getTime() >= anterior.ini.getTime() &&
                    p.fechaInicio.getTime() <= anterior.fin.getTime()){
                    // El practicante Inicio en el Periodo Anterior
                    // Se encuentra en la prefactura anterior?
                    retro = ConsultaRetro(anterior,p);
                    if(!retro){
                        //El practicante NO fue cobrado en la prefactura/periodo anterior
                        //Se cobra el seguro en este periodo
                        p.inicia = true;

                    }
            }

        }

    }

    private boolean ConsultaRetro(Periodo periodo, Practicante p) {
        String sql = "select fk_convenioid from facturapartida where fk_periodoid =";
        sql += periodo.index + " fk_convenioid = " + p.id;
        DBWRAP db=new DBWRAP();
        ResultSet rs;
        try {
            rs = db.select(sql); // Consulta
            while(rs.next()){
                if(db!=null){
                    db.close();
                    db=null;
                }
                return true;
            }

        } catch (SQLException ex) {
            if(db!=null){
                    db.close();
                    db=null;
            }
            Logger.getLogger(PrefacturaMO.class.getName()).log(Level.SEVERE, null, ex);
        }finally{
            if(db!=null){
                    db.close();
                    db=null;
            }
        }
        return false;
    }

    private void PagaSeguroSiguientePeriodo(int empresa,Periodo actual, Practicante p) {
        // Buscar cual es el Siguiente Periodo
        List<Periodo> periodos = getPeriodos(empresa,0,null);
        long offset=0;
        final long DIA = 3600*24*1000;

        if(periodos.size() <= 0) {
            // Error NO hay periodos, en teoria nunca debe de pasar por aqui
            return;
        }
        Periodo siguiente = null;

        for(Iterator ix = periodos.iterator();ix.hasNext();){
            Periodo per = (Periodo) ix.next();
            Date inicio = per.ini;
            offset =  per.ini.getTime() - actual.fin.getTime();
            if(offset == DIA){
                siguiente = per;
                break; // Encontramos el Periodo Siguiente
            }
        }

        if(siguiente == null){
            // No existe un nuevo Periodo
            return;
        }

        // Borra todas las deducciones de CAINTRA en el siguiente periodo del practicante.
        String sql = "delete from facturaajuste where fk_periodoid = " + siguiente.index;
        sql +=  " and fk_convenioid = " + p.id;
        DBWRAP db=new DBWRAP();
        try {
            db.update(sql);
            if(db!=null){
                    db.close();
                    db=null;
            }
        } catch (SQLException ex) {
            if(db!=null){
                    db.close();
                    db=null;
            }
            Logger.getLogger(PrefacturaMO.class.getName()).log(Level.SEVERE, null, ex);
        }finally{
            if(db!=null){
                    db.close();
                    db=null;
            }
        }

        // Le agrega una deduccion al siguiente periodo por la cantidad del seguro

        sql = "insert into facturaajuste(factor,cometario,tiempo,fk_convenioid,interno,fk_periodoid) values(";
        sql += p.poliza.costo * -1;
        sql += ",'Cobro de Seguro Retroactivo',";
        sql += "FALSE,";
        sql += p.id + ",";
        sql += "TRUE,";
        sql += siguiente.index + ")";
        db=new DBWRAP();
        try {
            db.update(sql);
            if(db!=null){
                    db.close();
                    db=null;
            }
        } catch (SQLException ex) {
            if(db!=null){
                    db.close();
                    db=null;
            }
            Logger.getLogger(PrefacturaMO.class.getName()).log(Level.SEVERE, null, ex);
        }finally{
            if(db!=null){
                    db.close();
                    db=null;
            }
        }


    }

    private boolean QueryPracticantesInsoventes(int empresa, Periodo periodo, List<Practicante> practicantes) {

        boolean resp = false;

        for(Iterator it = practicantes.iterator();it.hasNext();)
        {
            Practicante p = (Practicante) it.next();

            if(p.poliza == null)continue; //NO tiene seguro, esta excento de este proceso

            if(p.apagar < p.polizaPracticante){
                // El Practicante NO puede Pagar el Seguro en este Periodo
                // Vemos si el practicante puede pagar en el proximo Periodo
                double apagar = (p.sueldo / 30) * periodo.diaspagar;
                if(apagar >= p.poliza.costo)
                {
                    // El practicate puede pagar el seguro en el periodo siguiente
                    // Se quita el Seguro de Esta quincena, se genera una deduccion para el proximo
                    // periodo
                    PagaSeguroSiguientePeriodo(empresa,periodo,p);
                    p.polizaPracticante = 0;
                    resp= true;

                }else
                {
                    // El practicante NO puede pagar su Seguro en el Periodo Siguiente y
                    // se queda en Negativo, el usuario tiene que ajustar para que pueda pagarlo
                }


            }
        }

        return resp;
    }

    public double getAbonoTotal() {
        return AbonoTotal;
    }

    public void setAbonoTotal(double AbonoTotal) {
        this.AbonoTotal = AbonoTotal;
    }

    public double getAdeudoTotal() {
        return AdeudoTotal;
    }

    public void setAdeudoTotal(double AdeudoTotal) {
        this.AdeudoTotal = AdeudoTotal;
    }

    public ArrayList<Integer> getIds() {
        return ids;
    }

    public void setIds(ArrayList<Integer> ids) {
        this.ids = ids;
    }

    //AGREGADO DE PREFACTURAMO DEL SAPRA PARA LA DISPERSION
    public ArrayList<Practicante> practicanteFactura(int empresa,Periodo periodo) {

        m_practicantes = new ArrayList<Practicante>();
        ArrayList<Practicante> listaP=new ArrayList<Practicante>();
        DefaultTableModel tablemodel;
        m_empresa = empresa;
        m_periodo = periodo;
        boolean existe = false;
        // REVISA LA EXISTENCIA DE LA PREFACTURA
        m_factura = QueryFactura(periodo);

            // GENERA LA PREFACTURA
            // Se buscan los Practicantes a los que se le tiene que pagar
            QueryVigentes(empresa,periodo,m_practicantes); //Generico
            QueryVigProxCancelar(empresa,periodo,m_practicantes); // Generico que cancela despues
            QueryInician(empresa,periodo,m_practicantes); //Inician en Periodo
            QueryTerminan(empresa,periodo,m_practicantes); //Terminan en el Periodo
            QueryCancelan(empresa,periodo,m_practicantes); //Cancelan en el Periodo

            // Buscar los Numero de Cuenta (Ultimo Numero de Cuenta)
            QueryCuentas(empresa,periodo,m_practicantes);

            // Buscar su la Poliza relacionada al Convenio y Calcula el Monto a Pagar si Aplica
            QuerySeguros(dLogin.getEmpresa(),periodo,m_practicantes);

            // CONSULTA LOS DEPARTAMENTOS
            QueryDepartamentos(m_practicantes);

            // CONSULTA LOS CENTROS DE COSTO
            QueryCentrosCostos(m_practicantes);

            // Integra los Duplicados
            if(m_practicantes.size()>0)
                blend(m_practicantes,periodo);

            // CONSULTA LOS AJUSTES/DEDUCCIONES
            QueryAjustes(m_practicantes,periodo);


            // Calcula los Netos
            if(m_practicantes.size()>0)
                 CalculaNetos(m_practicantes,periodo);

            // Busca/Corrige a los Practicantes que NO pueden pagar su seguro
            if( QueryPracticantesInsoventes(empresa,periodo,m_practicantes) ){
                CalculaNetos(m_practicantes,periodo);
            }


         DecimalFormat nf = new DecimalFormat("#.00");
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MMM-dd",new Locale("es"));

        listaP=(ArrayList<Practicante>)m_practicantes;
        System.out.println(m_practicantes.toString());
        return listaP;

    }




}


            //if(p.id==19832)
              //      p.poliza.meses=2;

/*
            if(p.poliza.pagado==0 && p.poliza.meses != 1){
                // Si es un Practicante de Nuevo Ingreso que entra en este Periodo
                if(p.poliza.pagaempresa)
                    p.polizaEmpresa = p.poliza.costo / 1.16; // La empresa paga IVA total
                else{
                    // El practicante PAGA el Seguro
                    p.polizaPracticante = p.poliza.costo;
                }

            }else {
                // NO es de nuevo ingreso
                if(p.poliza.meses != 1 && p.poliza.pagado==1)continue; // Ya pago su seguro porque fue de Termino

                // Excepcion para Polizas de Duracion de Un mes
                offset = p.fechaTermino.getTime() - p.fechaInicio.getTime();
                offset = offset / (1000*60*60*24); // Saca los Dias del Convenio
                if(offset <= 31){
                    //Es un covenio menor o igual a 1 mes
                    //Se asume que la Poliza la Pago en el Primer Periodo
                    continue;
                }

                if(diaprimero){
                    //Si es el primer periodo del mes y su poliza por mes, se cobra
                    if(p.poliza.pagaempresa)
                        p.polizaEmpresa = p.poliza.costo / 1.16; // La empresa paga IVA total
                    else
                        p.polizaPracticante = p.poliza.costo;
                }
           }
*/